<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .te-point {}

        .te-line {}

        #start {
            border: 1px solid red;
            height: 50px;
            width: 50px;
            position: absolute;
            left: 50%;
            top: 50%;
        }

        #end {
            border: 1px solid red;
            height: 50px;
            width: 50px;
            position: absolute;
            left: 100px;
            top: 100px;
        }

        #writeBorad {
            position: relative;
            top: 1px;
            left: 1px;
            height: 700px;
            width: 1000px;
            border: 1pt solid red;
        }

        * .yv-selected-line {
            border: 1px solid red;

        }
    </style>
</head>

<body>
    点击 1 开始画线 双击画板结束画线 双击线段选中线条
    <div id="writeBorad">
        <div id="start" onclick="startEvent">1</div>
        <div id="lineWriter"></div>
        <div id="globalLineWriter"></div>
    </div>
    <button id="submitSave">提交</button>
    <!-- <button id="getSave">加载数据</button> -->
    <input type="file" accept=".wTmpl" id="getSaveData">


    <script>
        // 保存数据
        var submitSave = document.getElementById('submitSave');
        submitSave.onclick = async function saveFile() {
            try {
                const opts = {
                    types: [
                        {
                            description: 'WebsiteTemplate（网站模板）文件 .wTmpl',
                            accept: {
                                'text/plain': ['.wTmpl'],
                            }
                        }
                    ],
                    excludeAcceptAllOption: true
                };

                const handle = await window.showSaveFilePicker(opts); // 打开保存文件对话框
                const writable = await handle.createWritable(); // 创建可写入的文件对象
                // 加密
                var fileContent = `<{WebsiteTemplate:Start}>${document.getElementById('writeBorad').innerHTML}<{WebsiteTemplate:Ended}>`;
                var result = btoa(encodeURIComponent(fileContent));
                // 写入文件内容
                await writable.write(result);
                await writable.close();

                console.log('文件保存成功');
                window.alert('success');
            } catch (error) {
                console.error('文件保存失败:', error);
            }
        }

        // 加载数据
        var getSaveData = document.getElementById('getSaveData');
        getSaveData.onchange = async function getFile(e) {
            //获取文件对象
            var file = e.target.files[0];
            console.log(file)
            //读取文件内容
            var reader = new FileReader();
            reader.readAsText(file);
            reader.onload = function (e) {
                var val = e.target.result;
                const decoed = decodeURIComponent(atob(val));
                if (decoed.startsWith('<{WebsiteTemplate:Start}>') && decoed.endsWith('<{WebsiteTemplate:Ended}>')) {
                    document.getElementById('writeBorad').innerHTML = decoed.replace('<{WebsiteTemplate:Start}>', '').replace('<{WebsiteTemplate:Ended}>', '')
                    loadEvent();
                } else {
                    window.alert('加载失败：错误的文件')
                }
            }
        }

        var globalLines = [];
        var tempLines = [];
        var watchMouse = false;
        var inPress = false;
        var temp = null;

        // var selectedLine = [];

        loadEvent();

        var borad = document.getElementById("writeBorad");


        function loadEvent() {
            //画板
            borad = document.getElementById("writeBorad");

            //监听回调
            const myCallBack = (e) => {
                watchMouseFunc(e);
            }

            //双击结束箭头
            borad.ondblclick = function endEvent() {
                if (watchMouse == true) {
                    watchMouse = false;
                    console.log("endEvent")
                    borad.removeEventListener("mousemove", myCallBack);
                    confirmLine();
                    console.log("ALL LINES =>", globalLines)
                }
            }

            //点击开始箭头
            var startElement = document.getElementById("start");
            startElement.onclick = function startEvent() {
                watchMouse = true;
                borad.addEventListener("mousemove", myCallBack)
            }

            //点击连线
            // var lineWriter = document.getElementsByClassName("yv-line-origin");
            // lineWriter.onclick = function lineEvent() {
            //     console.log("You click me")
            // }

            lineWatchClick();
        }

        //监听
        function watchMouseFunc(e) {
            var startElement = document.getElementById("start");
            var start = [startElement.offsetLeft, startElement.offsetTop];
            var pxLoad = 1;
            if (temp == null
                ||
                (e.pageX < temp[0] - pxLoad || e.pageX > temp[0] + pxLoad)
                ||
                (e.pageY < temp[1] - pxLoad || e.pageY > temp[1] + pxLoad)) {
                if (temp != null) {
                    cancelLine();
                }
                temp = [e.pageX, e.pageY];
                compute(start, [e.pageX - borad.offsetLeft, e.pageY - borad.offsetTop]);
            }
        }

        //计算 Changed
        //type: 0 左右直线 1 上下直线
        function compute(start, end, type = 0) {
            if (inPress) return;
            //获取结束点在起始点的方位
            //  //      startY
            //  //        +   
            //  //        ^
            //  //+ +     |    - +
            //  //        |
            //  - ========0========> + startX
            //  //        |
            //  //+ -     |     - -
            //  //        -
            var cX = start[0] - end[0];
            var cY = start[1] - end[1];
            // 如果x是0
            if (cX == 0) {
                spawnLine(start[0], start[1], Math.abs(cY), cY > 0 ? 270 : 90);
            }
            // 如果y是0
            if (cY == 0) {
                spawnLine(start[0], start[1], Math.abs(cX), cX > 0 ? 180 : 0);

            }
            if (cX != 0 && cY != 0) {
                var xDeg = cX < 0 ? 0 : 180;
                switch (type) {
                    case 0:
                        //右下 || 左上
                        if (cX < 0 && cY != 0) {
                            let lineResult = spawnLine(start[0], start[1], Math.abs(cX), 0);
                            spawnLine(lineResult[1], start[1], Math.abs(cY), cY < 0 ? 90 : 270);
                        }
                        //左下 || 右上
                        if (cX > 0 && cY != 0) {
                            let lineResult = spawnLine(start[0], start[1], Math.abs(cX), xDeg, xDeg);
                            spawnLine(start[0] - Math.abs(start[0] - lineResult[1]), start[1], Math.abs(cY), cY < 0 ? 90 : 270);
                        }
                        break;
                    case 1:
                        if (cY < 0 && cX != 0) {
                            let lineResult = spawnLine(start[0], start[1], Math.abs(cY), 90, 180);
                            spawnLine(start[0], start[1] + (lineResult[1] - lineResult[0]), Math.abs(cX), xDeg, xDeg);
                        }
                        if (cY > 0 && cX != 0) {
                            let lineResult = spawnLine(start[0], start[1], Math.abs(cY), 270, 90);
                            spawnLine(start[0], start[0] - Math.abs(start[1] - lineResult[1]), Math.abs(cX), xDeg, xDeg);
                        }
                        break;
                }
            }
        }

        /**
         * 所有线条全部选中
         **/

        /**
         * 确认生成
         **/
        function confirmLine() {
            inPress = true;
            globalLines.push(tempLines);
            document.getElementById("globalLineWriter").innerHTML +=
                `<div class="yv-line-super" id="yv-line-super-${spawnId("yv-line-super-")}">${document.getElementById("lineWriter").innerHTML}</div>`;
            temp = null;
            inPress = false;
            cancelLine();
            inPress = true;
            //给每个都增加点击事件
            lineWatchClick();
            inPress = false;
        }

        /**
         * 给每个线条都增加点击事件 Changed
         **/
        function lineWatchClick() {
            var elements = document.getElementsByClassName("yv-line-super");
            for (var i = 0; i < elements.length; i++) {
                if (elements[i]) {
                    for (var j = 0; j < elements[i].children.length; j++) {
                        elements[i].children[j].ondblclick = (e) => {
                            cancelSelectLine();
                            selectLine(e)
                        }
                        console.log(elements[i].children[j].getElementsByClassName("yv-line-input")[0])
                        elements[i].children[j].getElementsByClassName("yv-line-input")[0].onchange = (e) => {
                            console.log(document.getElementById(e.target.id))
                            document.getElementById(e.target.id).setAttribute('value', e.target.value);
                            //  = e.target.value;
                        }
                    }
                }
            }
        }

        /** 
         * 选中线条
         **/
        function selectLine(event) {
            const clickedId = event.target.id;
            var lineId = clickedId.includes("-origin")
                ? clickedId.substring(0, clickedId.indexOf("-origin"))
                : clickedId;
            //在数组中查询线段所在的全部线条
            var lineSuper = document.getElementById(lineId).parentElement;
            var lineElement = lineSuper.children;
            var lineElementArr = [];
            //给全部线条增加样式
            if (lineElement.length != 0) {
                lineElementArr = Array.from(lineElement);
            } else {
                return;
            }
            for (var i = 0; i < lineElementArr.length; i++) {
                lineElementArr[i].classList.add("yv-selected-line");
            }
        }

        /**
         * 取消选中
         **/
        function cancelSelectLine() {
            var element = document.getElementsByClassName("yv-selected-line");
            console.log(element.length)
            if (element.length == 0) {
                return;
            }
            var selectedLineArr = Array.from(element);
            console.log(selectedLineArr)
            for (var q = 0; q < selectedLineArr.length; q++) {
                selectedLineArr[q].classList.remove("yv-selected-line");
            }
        }

        /**
         * 放弃生成
         **/
        function cancelLine() {
            inPress = true;
            for (var i = 0; i < tempLines.length; i++) {
                let element = document.getElementById(tempLines[i]);
                if (element)
                    element.remove();
            }
            tempLines = [];
            document.getElementById("lineWriter").innerHTML = "";
            inPress = false;
        }

        /**
         * 生成线段 Changed
         **/
        function spawnLine(startX, startY, range, deg = 0, inputDeg, only = false, border = '1px solid #000') {
            var lineId = spawnId('yv-line-');
            document.getElementById("lineWriter").innerHTML +=
                `${only == true ? `<div class="yv-line-super" id="yv-line-super-${spawnId("yv-line-super-")}">` : ''}<div style="
                position: absolute; 
                margin-top: ${startY}px;
                margin-left: ${startX}px;
                height: 0px;
                border-radius: 0;
                z-index: 1;
                width: ${range}px; 
                border-top: ${border}; 
                transform: rotate(${deg}deg); 
                transform-origin: left top;" 
                class="yv-line-base"
                id="yv-line-${lineId}">
                    <input type="text" id="yv-line-${lineId}-input" class="yv-line-input" 
                    style="
                    outline: none;
                    border: none;
                    transform: rotate(${inputDeg}deg);
                    z-index: 0;
                    background: transparent;
                    text-align: center;
                    margin: 0;
                    padding: 0;
                    position: absolute;
                    font-size: 12px;
                    width: 100%"></input>
                    <div id="yv-line-${lineId}-origin" class="yv-line-origin" style="z-index: 1;height: 10px; border-radius: 5px;width:100%;background: transparent; position: absolute; top: -5px; border-radius: 1px;"></div>
                </div>
                ${only == true ? `</div>` : ''}`;
            tempLines.push(`yv-line-${lineId}`);
            let ele = document.getElementById(`yv-line-${lineId}`);
            return [ele.offsetLeft, ele.offsetLeft + range];
        }

        //生成线段ID
        function spawnId(prefix, size = 24) {
            while (true) {
                var id = random(size);
                if (!document.getElementById(prefix + id)) {
                    return id;
                }
            }
        }

        //随机数
        function random(size) {
            var result = '';
            let array = [
                '1', '2', '3', '4', '5', '6', '7', '8', '9', '0',
                '*', '(', ')', '&', '^', '%', '$', '#', '@', '!',
                'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
                'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
                'u', 'v', 'w', 'x', 'y', 'z',
                'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
                'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
                'U', 'V', 'W', 'X', 'Y', 'Z'
            ];
            for (var i = 0; i < size; i++) {
                result += array[Math.floor(Math.random() * array.length)];
            }
            return result;
        }
    </script>
</body>

</html>